# coding = utf-8
import logging
import os
import time

from django.forms.models import model_to_dict
from django.db.models import Q
from lawoffice import settings
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from case.api.serializers import CaseSerializer, LetterSerializer, IntroduceSerializer, ProgressSerializer, \
    CaseProgressSerializer, ReasonSerializer, CriminalIntroduceSerializer, CaseFileSerializer, ProgressParentSerializer, \
    CaseSimpleSerializer
from case.models import Case, Letter, Introduce, Progress, CaseProgress, Reason, CriminalIntroduce, CaseFile
from users.models import UserInfo


logger = logging.getLogger("django")


class CaseViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = [AllowAny]
    queryset = Case.objects.all()
    serializer_class = CaseSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        case_type = self.request.query_params.get("case_type")
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")
        reason = self.request.query_params.get("reason")
        archive_flag = self.request.query_params.get("archive_flag")
        print("archive_flag:", archive_flag)
        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(Q(lead_lawyer=user) | Q(assist_lawyer=user) | Q(third_lawyer=user) | Q(user=user))

        if archive_flag == "1":
            queryset = queryset.filter(archive_flag=True)
        else:
            queryset = queryset.filter(archive_flag=False)

        if case_type:
            queryset = queryset.filter(case_type=case_type)

        if name:
            queryset = queryset.filter(Q(client__contains=name) | Q(party__contains=name) | Q(lead_lawyer__real_name__contains=name) | Q(assist_lawyer__real_name__contains=name) | Q(recv_lawyer__contains=name) )

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(recv_time__range=(search_date[0], search_date[1]))

        if reason:
            queryset = queryset.filter(reason__contains=reason)

        return queryset


class CaseListAPIView(ListAPIView):
    # authentication_classes = ()
    permission_classes = [AllowAny]
    pagination_class = None
    queryset = Case.objects.all()
    serializer_class = CaseSimpleSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(Q(lead_lawyer=user) | Q(assist_lawyer=user) | Q(user=user))

        case_type = self.request.query_params.get("case_type", None)

        if case_type:
            queryset = queryset.filter(case_type=case_type)

        return queryset


class CaseSearchAPIView(ListAPIView):
    # authentication_classes = ()
    permission_classes = [AllowAny]
    pagination_class = None
    queryset = Case.objects.all()
    serializer_class = CaseSimpleSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        party = self.request.query_params.get("party", None)
        oppo_party = self.request.query_params.get("oppo_party", None)
        # print(party, oppo_party)
        if not party and not oppo_party:

            return None

        if party:
            queryset = queryset.filter(party__contains=party)

        if oppo_party:
            queryset = queryset.filter(oppo_party__contains=oppo_party)

        return queryset


class LetterViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = Letter.objects.all()
    serializer_class = LetterSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(case__code__contains=name) | Q(client__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(apply_time__date__range=(search_date[0], search_date[1]))

        return queryset


class LetterStampViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = Letter.objects.filter(apply_confirm=True).order_by('stamp_confirm', '-apply_time')
    serializer_class = LetterSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        # print(self.request.user)

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(case__code__contains=name) | Q(client__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(apply_time__date__range=(search_date[0], search_date[1]))

        return queryset


class IntroduceViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = Introduce.objects.all()
    serializer_class = IntroduceSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(case__code__contains=name) | Q(court__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(apply_time__date__range=(search_date[0], search_date[1]))

        return queryset


class IntroduceStampViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = Introduce.objects.filter(apply_confirm=True).order_by('stamp_confirm', '-apply_time')
    serializer_class = IntroduceSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(case__code__contains=name) | Q(court__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(apply_time__date__range=(search_date[0], search_date[1]))

        return queryset


class ProgressParentViewSet(ReadOnlyModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    pagination_class = None
    queryset = Progress.objects.filter(parent__isnull=True)
    serializer_class = ProgressParentSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        case_type = self.request.query_params.get("case_type", None)
        if case_type:
            queryset = queryset.filter(case_type=case_type)
        return queryset


class ProgressTreeViewSet(ReadOnlyModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    pagination_class = None
    queryset = Progress.objects.filter(parent__isnull=True)
    serializer_class = ProgressSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        case_type = self.request.query_params.get("case_type", None)
        if case_type:
            queryset = queryset.filter(case_type=case_type)
        return queryset


class ProgressViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    pagination_class = None
    queryset = Progress.objects.all()
    serializer_class = ProgressSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        case_type = self.request.query_params.get("case_type", None)
        if case_type:
            queryset = queryset.filter(case_type=case_type)
        return queryset

    @action(methods=['patch'], detail=False)
    def batch_update(self, request, *args, **kwargs):
        update_ids = request.data["update_ids"]
        print(update_ids)
        if not isinstance(update_ids, list):
            msg = {"status_code": status.HTTP_404_NOT_FOUND, "message": "更新失败!"}
            return Response(data=msg, status=status.HTTP_404_NOT_FOUND)

        data = {item["id"]: item for item in update_ids}

        queryset = self.get_queryset().filter(id__in=data.keys())
        for inst in queryset:
            serializer = self.get_serializer(inst, data=data[inst.id], partial=True)
            serializer.is_valid(raise_exception=True)
            serializer.save()
        msg = {"status_code": status.HTTP_200_OK, "message": "更新成功!"}
        return Response(data=msg, status=status.HTTP_200_OK)


class CaseProgressViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    pagination_class = None
    queryset = CaseProgress.objects.all()
    serializer_class = CaseProgressSerializer


class ReasonViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = Reason.objects.all()
    serializer_class = ReasonSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")

        if name:
            queryset = queryset.filter(name__contains=name)

        return queryset


class ReasonListAPIView(ListAPIView):
    # authentication_classes = ()
    permission_classes = [AllowAny]
    pagination_class = None
    queryset = Reason.objects.all()
    serializer_class = ReasonSerializer


class CriminalIntroduceViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = CriminalIntroduce.objects.all()
    serializer_class = CriminalIntroduceSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(court__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(add_time__date__range=(search_date[0], search_date[1]))

        return queryset


class CriminalIntroduceStampViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = CriminalIntroduce.objects.filter(apply_confirm=True).order_by('stamp_confirm', '-apply_time')
    serializer_class = CriminalIntroduceSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name")
        search_date = self.request.query_params.getlist("search_date[]")

        user = self.request.user
        if not isinstance(user, UserInfo):
            return None

        if not user.is_superuser:
            count = user.roles.filter(only_own=True).count()
            if count > 0:
                queryset = queryset.filter(user=user)

        if name:
            queryset = queryset.filter(Q(code__contains=name) | Q(court__contains=name) | Q(party__contains=name))

        if search_date and len(search_date) == 2:
            queryset = queryset.filter(apply_time__date__range=(search_date[0], search_date[1]))

        return queryset


class CaseFileViewSet(ModelViewSet):
    # authentication_classes = ()
    permission_classes = (AllowAny,)
    queryset = CaseFile.objects.all()
    serializer_class = CaseFileSerializer


class FileUploadAPIView(APIView):

    def post(self, request, *args, **kwargs):
        # 接收文件
        file = request.FILES.get('file', None)
        case_id = request.data.get("case_id", None)

        if file:
            upload_path = CaseFile.file.field.upload_to
            dirs = os.path.join(settings.MEDIA_ROOT, upload_path)
            if not os.path.exists(dirs):
                os.makedirs(dirs)

            file_info = file.name.split(".")
            old_file_name = file_info[0]
            file_suffix = file_info[1]
            file_name = '{0}_{1}.{2}'.format(old_file_name, int(time.time()), file_suffix)
            file_path = os.path.join(dirs, file_name)

            with open(file_path, 'wb') as f:
                for chunk in file.chunks():
                    f.write(chunk)

            file_url = '{0}{1}'.format(upload_path, file_name)
            data = {
                'case_id': case_id if case_id != "null" else None,
                'name': file.name,
                'file': file_url,
            }

            obj = CaseFile.objects.create(**data)
            dict_obj = {
                "id": obj.id,
                "name": obj.name,
                "case": obj.case_id,
                "file": "{}://{}{}".format(request.scheme, request.get_host(), obj.file.url),
            }

            msg = {
                "status_code": status.HTTP_200_OK,
                "file": dict_obj,
            }
            return Response(msg)

        return Response({"status_code": status.HTTP_401_UNAUTHORIZED, "message": "上传失败!"})

